package lhttp

import (
	"bytes"
	"crypto/tls"
	"net"
	"net/http"
	"net/url"
	"time"

	"go.uber.org/zap"
)

func NewClient(logger *zap.Logger, rawUrl string) *Client {
	urlRUL, err := url.Parse(rawUrl)
	if err != nil {
		logger.Fatal(
			"[http请求]地址解析失败", zap.String("url", rawUrl), zap.Error(err),
		)
	}

	tr := &http.Transport{
		DialContext: (&net.Dialer{
			Timeout:   30 * time.Second,
			KeepAlive: 30 * time.Second,
		}).DialContext,
		ForceAttemptHTTP2:     true,
		MaxIdleConns:          100,
		IdleConnTimeout:       90 * time.Second,
		ExpectContinueTimeout: 1 * time.Second,
	}
	if urlRUL.Scheme == "https" {
		tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
		tr.TLSHandshakeTimeout = 10 * time.Second
	}

	return &Client{
		url:    rawUrl,
		client: &http.Client{Transport: tr},
	}
}

type Client struct {
	url    string
	client *http.Client
	logger *zap.Logger
}

func (c *Client) Request(method string, header map[string]string, data []byte) *http.Response {
	req, err := http.NewRequest(method, c.url, bytes.NewReader(data))
	if err != nil {
		c.logger.Error("[http请求]构建请求失败", zap.Error(err))
		return nil
	}

	for key, value := range header {
		req.Header.Set(key, value)
	}

	resp, err := c.client.Do(req)
	if err != nil {
		c.logger.Error("[http请求]请求失败", zap.Error(err))
		return nil
	}
	return resp
}
